package com.Async;

import com.serializetool.Response;

import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class RpcFuture implements Future,Observer{

    long taskId;

    Callback callback;

    Long retryMs;

    Object result;

    Throwable error;

    boolean success;

    boolean cancelled;

    int retryTime;

    InetSocketAddress socket;

    String serviceName;

    public RpcFuture(){
    }


    public void setTaskId(Long id){
        this.taskId = id;
    }

    public RpcFuture(long taskId,Callback callback){
        this.taskId =taskId;
        this.callback = callback;
    }

    public void setRetryMs(Long retryMs) {
        this.retryMs = retryMs;
    }

    public void setCallback(Callback callback){
        this.callback = callback;
    }


    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        cancelled = true;
        return true;
    }

    @Override
    public boolean isCancelled() {
        return cancelled;
    }

    @Override
    public boolean isDone() {
        return result!=null||error!=null||isCancelled();
    }

    @Override
    public Object get(){
       while(success==false&&error==null){
           System.out.print("");
       }

//       System.out.println("future已获得结果");
       if(error!=null){
           try {
               throw error;
           } catch (Throwable throwable) {
               throwable.printStackTrace();
           }
       }
        return result;
    }

    @Override
    public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        long time = System.currentTimeMillis();
        Response response = null;
        while(this.result==null&&System.currentTimeMillis()-time< unit.toMicros(timeout)){
            Thread.sleep(retryMs);
        }
        return result;
    }


    @Override
    public void setValue(Object o) {
        this.result = o;
    }

    public void tryRunCallBack(){
        if(callback==null) return;
        if(!success){
            if(error!=null) callback.onFailure((Throwable) result);
            else System.out.println("未捕获的异常错误");
        }else{
            callback.onSuccess(result);
        }
    }

    public Object getResult() {
        return result;
    }

    public void setResult(Object result) {
        this.result = result;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public Throwable getError() {
        return error;
    }

    public void setError(Throwable error) {
        this.error = error;
    }

    public boolean isSuccess() {
        return success;
    }

    public boolean cancelled(){return cancelled;}

    public int getRetryTime() {
        return retryTime;
    }

    public void setRetryTime(int retryTime) {
        this.retryTime = retryTime;
    }

    public InetSocketAddress getSocket() {
        return socket;
    }

    public void setSocket(InetSocketAddress socket) {
        this.socket = socket;
    }

    public String getServiceName() {
        return serviceName;
    }

    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }
}
